home *** CD-ROM | disk | FTP | other *** search
Text File | 2002-10-03 | 59.2 KB | 1,651 lines |
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- NNNNAAAAMMMMEEEE
- perlxs - XS language reference manual
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- IIIInnnnttttrrrroooodddduuuuccccttttiiiioooonnnn
-
- XS is a language used to create an extension interface between Perl and
- some C library which one wishes to use with Perl. The XS interface is
- combined with the library to create a new library which can be linked to
- Perl. An XXXXSSSSUUUUBBBB is a function in the XS language and is the core component
- of the Perl application interface.
-
- The XS compiler is called xxxxssssuuuubbbbpppppppp. This compiler will embed the
- constructs necessary to let an XSUB, which is really a C function in
- disguise, manipulate Perl values and creates the glue necessary to let
- Perl access the XSUB. The compiler uses ttttyyyyppppeeeemmmmaaaappppssss to determine how to map
- C function parameters and variables to Perl values. The default typemap
- handles many common C types. A supplement typemap must be created to
- handle special structures and types for the library being linked.
-
- See the _p_e_r_l_x_s_t_u_t manpage for a tutorial on the whole extension creation
- process.
-
- Note: For many extensions, Dave Beazley's SWIG system provides a
- significantly more convenient mechanism for creating the XS glue code.
- See the section on /_w_w_w._c_s._u_t_a_h._e_d_u/~_b_e_a_z_l_e_y/_S_W_I_G in the _h_t_t_p: manpage
- for more information.
-
- OOOOnnnn TTTThhhheeee RRRRooooaaaadddd
-
- Many of the examples which follow will concentrate on creating an
- interface between Perl and the ONC+ RPC bind library functions. The
- _r_p_c_b__g_e_t_t_i_m_e() function is used to demonstrate many features of the XS
- language. This function has two parameters; the first is an input
- parameter and the second is an output parameter. The function also
- returns a status value.
-
- bool_t rpcb_gettime(const char *host, time_t *timep);
-
- From C this function will be called with the following statements.
-
- #include <rpc/rpc.h>
- bool_t status;
- time_t timep;
- status = rpcb_gettime( "localhost", &timep );
-
- If an XSUB is created to offer a direct translation between this function
- and Perl, then this XSUB will be used from Perl with the following code.
- The $status and $timep variables will contain the output of the function.
-
-
-
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- use RPC;
- $status = rpcb_gettime( "localhost", $timep );
-
- The following XS file shows an XS subroutine, or XSUB, which demonstrates
- one possible interface to the _r_p_c_b__g_e_t_t_i_m_e() function. This XSUB
- represents a direct translation between C and Perl and so preserves the
- interface even from Perl. This XSUB will be invoked from Perl with the
- usage shown above. Note that the first three #include statements, for
- EXTERN.h, perl.h, and XSUB.h, will always be present at the beginning of
- an XS file. This approach and others will be expanded later in this
- document.
-
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
- #include <rpc/rpc.h>
-
- MODULE = RPC PACKAGE = RPC
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
- Any extension to Perl, including those containing XSUBs, should have a
- Perl module to serve as the bootstrap which pulls the extension into
- Perl. This module will export the extension's functions and variables to
- the Perl program and will cause the extension's XSUBs to be linked into
- Perl. The following module will be used for most of the examples in this
- document and should be used from Perl with the use command as shown
- earlier. Perl modules are explained in more detail later in this
- document.
-
- package RPC;
-
- require Exporter;
- require DynaLoader;
- @ISA = qw(Exporter DynaLoader);
- @EXPORT = qw( rpcb_gettime );
-
- bootstrap RPC;
- 1;
-
- Throughout this document a variety of interfaces to the _r_p_c_b__g_e_t_t_i_m_e()
- XSUB will be explored. The XSUBs will take their parameters in different
- orders or will take different numbers of parameters. In each case the
- XSUB is an abstraction between Perl and the real C _r_p_c_b__g_e_t_t_i_m_e()
- function, and the XSUB must always ensure that the real _r_p_c_b__g_e_t_t_i_m_e()
- function is called with the correct parameters. This abstraction will
- allow the programmer to create a more Perl-like interface to the C
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- function.
-
- TTTThhhheeee AAAAnnnnaaaattttoooommmmyyyy ooooffff aaaannnn XXXXSSSSUUUUBBBB
-
- The following XSUB allows a Perl program to access a C library function
- called _s_i_n(). The XSUB will imitate the C function which takes a single
- argument and returns a single value.
-
- double
- sin(x)
- double x
-
- When using C pointers the indirection operator * should be considered
- part of the type and the address operator & should be considered part of
- the variable, as is demonstrated in the _r_p_c_b__g_e_t_t_i_m_e() function above.
- See the section on typemaps for more about handling qualifiers and unary
- operators in C types.
-
- The function name and the return type must be placed on separate lines.
-
- INCORRECT CORRECT
-
- double sin(x) double
- double x sin(x)
- double x
-
- The function body may be indented or left-adjusted. The following
- example shows a function with its body left-adjusted. Most examples in
- this document will indent the body.
-
- CORRECT
-
- double
- sin(x)
- double x
-
-
- TTTThhhheeee AAAArrrrgggguuuummmmeeeennnntttt SSSSttttaaaacccckkkk
-
- The argument stack is used to store the values which are sent as
- parameters to the XSUB and to store the XSUB's return value. In reality
- all Perl functions keep their values on this stack at the same time, each
- limited to its own range of positions on the stack. In this document the
- first position on that stack which belongs to the active function will be
- referred to as position 0 for that function.
-
- XSUBs refer to their stack arguments with the macro SSSSTTTT((((xxxx)))), where _x refers
- to a position in this XSUB's part of the stack. Position 0 for that
- function would be known to the XSUB as _S_T(0). The XSUB's incoming
- parameters and outgoing return values always begin at _S_T(0). For many
- simple cases the xxxxssssuuuubbbbpppppppp compiler will generate the code necessary to
- handle the argument stack by embedding code fragments found in the
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- typemaps. In more complex cases the programmer must supply the code.
-
- TTTThhhheeee RRRREEEETTTTVVVVAAAALLLL VVVVaaaarrrriiiiaaaabbbblllleeee
-
- The RETVAL variable is a magic variable which always matches the return
- type of the C library function. The xxxxssssuuuubbbbpppppppp compiler will supply this
- variable in each XSUB and by default will use it to hold the return value
- of the C library function being called. In simple cases the value of
- RETVAL will be placed in _S_T(0) of the argument stack where it can be
- received by Perl as the return value of the XSUB.
-
- If the XSUB has a return type of void then the compiler will not supply a
- RETVAL variable for that function. When using the PPCODE: directive the
- RETVAL variable is not needed, unless used explicitly.
-
- If PPCODE: directive is not used, void return value should be used only
- for subroutines which do not return a value, _e_v_e_n _i_f CODE: directive is
- used which sets _S_T(0) explicitly.
-
- Older versions of this document recommended to use void return value in
- such cases. It was discovered that this could lead to segfaults in cases
- when XSUB was _t_r_u_e_l_y void. This practice is now deprecated, and may be
- not supported at some future version. Use the return value SV * in such
- cases. (Currently xsubpp contains some heuristic code which tries to
- disambiguate between "truely-void" and "old-practice-declared-as-void"
- functions. Hence your code is at mercy of this heuristics unless you use
- SV * as return value.)
-
- TTTThhhheeee MMMMOOOODDDDUUUULLLLEEEE KKKKeeeeyyyywwwwoooorrrrdddd
-
- The MODULE keyword is used to start the XS code and to specify the
- package of the functions which are being defined. All text preceding the
- first MODULE keyword is considered C code and is passed through to the
- output untouched. Every XS module will have a bootstrap function which
- is used to hook the XSUBs into Perl. The package name of this bootstrap
- function will match the value of the last MODULE statement in the XS
- source files. The value of MODULE should always remain constant within
- the same XS file, though this is not required.
-
- The following example will start the XS code and will place all functions
- in a package named RPC.
-
- MODULE = RPC
-
-
- TTTThhhheeee PPPPAAAACCCCKKKKAAAAGGGGEEEE KKKKeeeeyyyywwwwoooorrrrdddd
-
- When functions within an XS source file must be separated into packages
- the PACKAGE keyword should be used. This keyword is used with the MODULE
- keyword and must follow immediately after it when used.
-
-
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- MODULE = RPC PACKAGE = RPC
-
- [ XS code in package RPC ]
-
- MODULE = RPC PACKAGE = RPCB
-
- [ XS code in package RPCB ]
-
- MODULE = RPC PACKAGE = RPC
-
- [ XS code in package RPC ]
-
- Although this keyword is optional and in some cases provides redundant
- information it should always be used. This keyword will ensure that the
- XSUBs appear in the desired package.
-
- TTTThhhheeee PPPPRRRREEEEFFFFIIIIXXXX KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PREFIX keyword designates prefixes which should be removed from the
- Perl function names. If the C function is rpcb_gettime() and the PREFIX
- value is rpcb_ then Perl will see this function as gettime().
-
- This keyword should follow the PACKAGE keyword when used. If PACKAGE is
- not used then PREFIX should follow the MODULE keyword.
-
- MODULE = RPC PREFIX = rpc_
-
- MODULE = RPC PACKAGE = RPCB PREFIX = rpcb_
-
-
- TTTThhhheeee OOOOUUUUTTTTPPPPUUUUTTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The OUTPUT: keyword indicates that certain function parameters should be
- updated (new values made visible to Perl) when the XSUB terminates or
- that certain values should be returned to the calling Perl function. For
- simple functions, such as the _s_i_n() function above, the RETVAL variable
- is automatically designated as an output value. In more complex
- functions the xxxxssssuuuubbbbpppppppp compiler will need help to determine which variables
- are output variables.
-
- This keyword will normally be used to complement the CODE: keyword. The
- RETVAL variable is not recognized as an output variable when the CODE:
- keyword is present. The OUTPUT: keyword is used in this situation to
- tell the compiler that RETVAL really is an output variable.
-
- The OUTPUT: keyword can also be used to indicate that function parameters
- are output variables. This may be necessary when a parameter has been
- modified within the function and the programmer would like the update to
- be seen by Perl.
-
-
-
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
- The OUTPUT: keyword will also allow an output parameter to be mapped to a
- matching piece of code rather than to a typemap.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep sv_setnv(ST(1), (double)timep);
-
- xxxxssssuuuubbbbpppppppp emits an automatic SvSETMAGIC() for all parameters in the OUTPUT
- section of the XSUB, except RETVAL. This is the usually desired
- behavior, as it takes care of properly invoking 'set' magic on output
- parameters (needed for hash or array element parameters that must be
- created if they didn't exist). If for some reason, this behavior is not
- desired, the OUTPUT section may contain a SETMAGIC: DISABLE line to
- disable it for the remainder of the parameters in the OUTPUT section.
- Likewise, SETMAGIC: ENABLE can be used to reenable it for the remainder
- of the OUTPUT section. See the _p_e_r_l_g_u_t_s manpage for more details about
- 'set' magic.
-
- TTTThhhheeee CCCCOOOODDDDEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword is used in more complicated XSUBs which require special
- handling for the C function. The RETVAL variable is available but will
- not be returned unless it is specified under the OUTPUT: keyword.
-
- The following XSUB is for a C function which requires special handling of
- its parameters. The Perl usage is given first.
-
- $status = rpcb_gettime( "localhost", $timep );
-
- The XSUB follows.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t timep
- CODE:
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TTTThhhheeee IIIINNNNIIIITTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The INIT: keyword allows initialization to be inserted into the XSUB
- before the compiler generates the call to the C function. Unlike the
- CODE: keyword above, this keyword does not affect the way the compiler
- handles RETVAL.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- INIT:
- printf("# Host is %s\n", host );
- OUTPUT:
- timep
-
-
- TTTThhhheeee NNNNOOOO____IIIINNNNIIIITTTT KKKKeeeeyyyywwwwoooorrrrdddd
-
- The NO_INIT keyword is used to indicate that a function parameter is
- being used only as an output value. The xxxxssssuuuubbbbpppppppp compiler will normally
- generate code to read the values of all function parameters from the
- argument stack and assign them to C variables upon entry to the function.
- NO_INIT will tell the compiler that some parameters will be used for
- output rather than for input and that they will be handled before the
- function terminates.
-
- The following example shows a variation of the _r_p_c_b__g_e_t_t_i_m_e() function.
- This function uses the timep variable only as an output variable and does
- not care about its initial contents.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep = NO_INIT
- OUTPUT:
- timep
-
-
- IIIInnnniiiittttiiiiaaaalllliiiizzzziiiinnnngggg FFFFuuuunnnnccccttttiiiioooonnnn PPPPaaaarrrraaaammmmeeeetttteeeerrrrssss
-
- Function parameters are normally initialized with their values from the
- argument stack. The typemaps contain the code segments which are used to
- transfer the Perl values to the C parameters. The programmer, however,
- is allowed to override the typemaps and supply alternate (or additional)
- initialization code.
-
- The following code demonstrates how to supply initialization code for
- function parameters. The initialization code is eval'd within double
- quotes by the compiler before it is added to the output so anything which
- should be interpreted literally [mainly $, @, or \\] must be protected
- with backslashes. The variables $var, $arg, and $type can be used as in
-
-
-
- PPPPaaaaggggeeee 7777
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- typemaps.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host = (char *)SvPV($arg,PL_na);
- time_t &timep = 0;
- OUTPUT:
- timep
-
- This should not be used to supply default values for parameters. One
- would normally use this when a function parameter must be processed by
- another library function before it can be used. Default parameters are
- covered in the next section.
-
- DDDDeeeeffffaaaauuuulllltttt PPPPaaaarrrraaaammmmeeeetttteeeerrrr VVVVaaaalllluuuueeeessss
-
- Default values can be specified for function parameters by placing an
- assignment statement in the parameter list. The default value may be a
- number or a string. Defaults should always be used on the right-most
- parameters only.
-
- To allow the XSUB for _r_p_c_b__g_e_t_t_i_m_e() to have a default host value the
- parameters to the XSUB could be rearranged. The XSUB will then call the
- real _r_p_c_b__g_e_t_t_i_m_e() function with the parameters in the correct order.
- Perl will call this XSUB with either of the following statements.
-
- $status = rpcb_gettime( $timep, $host );
-
- $status = rpcb_gettime( $timep );
-
- The XSUB will look like the code which follows. A CODE: block is
- used to call the real _r_p_c_b__g_e_t_t_i_m_e() function with the parameters in the
- correct order for that function.
-
- bool_t
- rpcb_gettime(timep,host="localhost")
- char *host
- time_t timep = NO_INIT
- CODE:
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee PPPPRRRREEEEIIIINNNNIIIITTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PREINIT: keyword allows extra variables to be declared before the
- typemaps are expanded. If a variable is declared in a CODE: block then
- that variable will follow any typemap code. This may result in a C
- syntax error. To force the variable to be declared before the typemap
- code, place it into a PREINIT: block. The PREINIT: keyword may be used
-
-
-
- PPPPaaaaggggeeee 8888
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- one or more times within an XSUB.
-
- The following examples are equivalent, but if the code is using complex
- typemaps then the first example is safer.
-
- bool_t
- rpcb_gettime(timep)
- time_t timep = NO_INIT
- PREINIT:
- char *host = "localhost";
- CODE:
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
- A correct, but error-prone example.
-
- bool_t
- rpcb_gettime(timep)
- time_t timep = NO_INIT
- CODE:
- char *host = "localhost";
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee SSSSCCCCOOOOPPPPEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The SCOPE: keyword allows scoping to be enabled for a particular XSUB. If
- enabled, the XSUB will invoke ENTER and LEAVE automatically.
-
- To support potentially complex type mappings, if a typemap entry used by
- this XSUB contains a comment like /*scope*/ then scoping will
- automatically be enabled for that XSUB.
-
- To enable scoping:
-
- SCOPE: ENABLE
-
- To disable scoping:
-
- SCOPE: DISABLE
-
-
- TTTThhhheeee IIIINNNNPPPPUUUUTTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The XSUB's parameters are usually evaluated immediately after entering
- the XSUB. The INPUT: keyword can be used to force those parameters to be
- evaluated a little later. The INPUT: keyword can be used multiple times
-
-
-
- PPPPaaaaggggeeee 9999
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- within an XSUB and can be used to list one or more input variables. This
- keyword is used with the PREINIT: keyword.
-
- The following example shows how the input parameter timep can be
- evaluated late, after a PREINIT.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- PREINIT:
- time_t tt;
- INPUT:
- time_t timep
- CODE:
- RETVAL = rpcb_gettime( host, &tt );
- timep = tt;
- OUTPUT:
- timep
- RETVAL
-
- The next example shows each input parameter evaluated late.
-
- bool_t
- rpcb_gettime(host,timep)
- PREINIT:
- time_t tt;
- INPUT:
- char *host
- PREINIT:
- char *h;
- INPUT:
- time_t timep
- CODE:
- h = host;
- RETVAL = rpcb_gettime( h, &tt );
- timep = tt;
- OUTPUT:
- timep
- RETVAL
-
-
- VVVVaaaarrrriiiiaaaabbbblllleeee----lllleeeennnnggggtttthhhh PPPPaaaarrrraaaammmmeeeetttteeeerrrr LLLLiiiissssttttssss
-
- XSUBs can have variable-length parameter lists by specifying an ellipsis
- (...) in the parameter list. This use of the ellipsis is similar to that
- found in ANSI C. The programmer is able to determine the number of
- arguments passed to the XSUB by examining the items variable which the
- xxxxssssuuuubbbbpppppppp compiler supplies for all XSUBs. By using this mechanism one can
- create an XSUB which accepts a list of parameters of unknown length.
-
-
-
-
-
-
- PPPPaaaaggggeeee 11110000
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- The _h_o_s_t parameter for the _r_p_c_b__g_e_t_t_i_m_e() XSUB can be optional so the
- ellipsis can be used to indicate that the XSUB will take a variable
- number of parameters. Perl should be able to call this XSUB with either
- of the following statements.
-
- $status = rpcb_gettime( $timep, $host );
-
- $status = rpcb_gettime( $timep );
-
- The XS code, with ellipsis, follows.
-
- bool_t
- rpcb_gettime(timep, ...)
- time_t timep = NO_INIT
- PREINIT:
- char *host = "localhost";
- CODE:
- if( items > 1 )
- host = (char *)SvPV(ST(1), na);
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee PPPPPPPPCCCCOOOODDDDEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PPCODE: keyword is an alternate form of the CODE: keyword and is used
- to tell the xxxxssssuuuubbbbpppppppp compiler that the programmer is supplying the code to
- control the argument stack for the XSUBs return values. Occasionally one
- will want an XSUB to return a list of values rather than a single value.
- In these cases one must use PPCODE: and then explicitly push the list of
- values on the stack. The PPCODE: and CODE: keywords are not used
- together within the same XSUB.
-
- The following XSUB will call the C _r_p_c_b__g_e_t_t_i_m_e() function and will
- return its two output values, timep and status, to Perl as a single list.
-
- void
- rpcb_gettime(host)
- char *host
- PREINIT:
- time_t timep;
- bool_t status;
- PPCODE:
- status = rpcb_gettime( host, &timep );
- EXTEND(SP, 2);
- PUSHs(sv_2mortal(newSViv(status)));
- PUSHs(sv_2mortal(newSViv(timep)));
-
- Notice that the programmer must supply the C code necessary to have the
- real _r_p_c_b__g_e_t_t_i_m_e() function called and to have the return values
-
-
-
- PPPPaaaaggggeeee 11111111
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- properly placed on the argument stack.
-
- The void return type for this function tells the xxxxssssuuuubbbbpppppppp compiler that the
- RETVAL variable is not needed or used and that it should not be created.
- In most scenarios the void return type should be used with the PPCODE:
- directive.
-
- The _E_X_T_E_N_D() macro is used to make room on the argument stack for 2
- return values. The PPCODE: directive causes the xxxxssssuuuubbbbpppppppp compiler to
- create a stack pointer available as SP, and it is this pointer which is
- being used in the _E_X_T_E_N_D() macro. The values are then pushed onto the
- stack with the _P_U_S_H_s() macro.
-
- Now the _r_p_c_b__g_e_t_t_i_m_e() function can be used from Perl with the following
- statement.
-
- ($status, $timep) = rpcb_gettime("localhost");
-
- When handling output parameters with a PPCODE section, be sure to handle
- 'set' magic properly. See the _p_e_r_l_g_u_t_s manpage for details about 'set'
- magic.
-
- RRRReeeettttuuuurrrrnnnniiiinnnngggg UUUUnnnnddddeeeeffff AAAAnnnndddd EEEEmmmmppppttttyyyy LLLLiiiissssttttssss
-
- Occasionally the programmer will want to return simply undef or an empty
- list if a function fails rather than a separate status value. The
- _r_p_c_b__g_e_t_t_i_m_e() function offers just this situation. If the function
- succeeds we would like to have it return the time and if it fails we
- would like to have undef returned. In the following Perl code the value
- of $timep will either be undef or it will be a valid time.
-
- $timep = rpcb_gettime( "localhost" );
-
- The following XSUB uses the SV * return type as a mnemonic only, and uses
- a CODE: block to indicate to the compiler that the programmer has
- supplied all the necessary code. The _s_v__n_e_w_m_o_r_t_a_l() call will initialize
- the return value to undef, making that the default return value.
-
- SV *
- rpcb_gettime(host)
- char * host
- PREINIT:
- time_t timep;
- bool_t x;
- CODE:
- ST(0) = sv_newmortal();
- if( rpcb_gettime( host, &timep ) )
- sv_setnv( ST(0), (double)timep);
-
- The next example demonstrates how one would place an explicit undef in
- the return value, should the need arise.
-
-
-
-
- PPPPaaaaggggeeee 11112222
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- SV *
- rpcb_gettime(host)
- char * host
- PREINIT:
- time_t timep;
- bool_t x;
- CODE:
- ST(0) = sv_newmortal();
- if( rpcb_gettime( host, &timep ) ){
- sv_setnv( ST(0), (double)timep);
- }
- else{
- ST(0) = &sv_undef;
- }
-
- To return an empty list one must use a PPCODE: block and then not push
- return values on the stack.
-
- void
- rpcb_gettime(host)
- char *host
- PREINIT:
- time_t timep;
- PPCODE:
- if( rpcb_gettime( host, &timep ) )
- PUSHs(sv_2mortal(newSViv(timep)));
- else{
- /* Nothing pushed on stack, so an empty */
- /* list is implicitly returned. */
- }
-
- Some people may be inclined to include an explicit return in the above
- XSUB, rather than letting control fall through to the end. In those
- situations XSRETURN_EMPTY should be used, instead. This will ensure that
- the XSUB stack is properly adjusted. Consult the section on _A_P_I _L_I_S_T_I_N_G
- in the _p_e_r_l_g_u_t_s manpage for other XSRETURN macros.
-
- TTTThhhheeee RRRREEEEQQQQUUUUIIIIRRRREEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The REQUIRE: keyword is used to indicate the minimum version of the
- xxxxssssuuuubbbbpppppppp compiler needed to compile the XS module. An XS module which
- contains the following statement will compile with only xxxxssssuuuubbbbpppppppp version
- 1.922 or greater:
-
- REQUIRE: 1.922
-
-
- TTTThhhheeee CCCCLLLLEEEEAAAANNNNUUUUPPPP:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword can be used when an XSUB requires special cleanup procedures
- before it terminates. When the CLEANUP: keyword is used it must follow
- any CODE:, PPCODE:, or OUTPUT: blocks which are present in the XSUB. The
-
-
-
- PPPPaaaaggggeeee 11113333
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- code specified for the cleanup block will be added as the last statements
- in the XSUB.
-
- TTTThhhheeee BBBBOOOOOOOOTTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The BOOT: keyword is used to add code to the extension's bootstrap
- function. The bootstrap function is generated by the xxxxssssuuuubbbbpppppppp compiler and
- normally holds the statements necessary to register any XSUBs with Perl.
- With the BOOT: keyword the programmer can tell the compiler to add extra
- statements to the bootstrap function.
-
- This keyword may be used any time after the first MODULE keyword and
- should appear on a line by itself. The first blank line after the
- keyword will terminate the code block.
-
- BOOT:
- # The following message will be printed when the
- # bootstrap function executes.
- printf("Hello from the bootstrap!\n");
-
-
- TTTThhhheeee VVVVEEEERRRRSSSSIIIIOOOONNNNCCCCHHHHEEEECCCCKKKK:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The VERSIONCHECK: keyword corresponds to xxxxssssuuuubbbbpppppppp's -versioncheck and
- -noversioncheck options. This keyword overrides the command line
- options. Version checking is enabled by default. When version checking
- is enabled the XS module will attempt to verify that its version matches
- the version of the PM module.
-
- To enable version checking:
-
- VERSIONCHECK: ENABLE
-
- To disable version checking:
-
- VERSIONCHECK: DISABLE
-
-
- TTTThhhheeee PPPPRRRROOOOTTTTOOOOTTTTYYYYPPPPEEEESSSS:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PROTOTYPES: keyword corresponds to xxxxssssuuuubbbbpppppppp's -prototypes and
- -noprototypes options. This keyword overrides the command line options.
- Prototypes are enabled by default. When prototypes are enabled XSUBs
- will be given Perl prototypes. This keyword may be used multiple times
- in an XS module to enable and disable prototypes for different parts of
- the module.
-
- To enable prototypes:
-
- PROTOTYPES: ENABLE
-
- To disable prototypes:
-
-
-
- PPPPaaaaggggeeee 11114444
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- PROTOTYPES: DISABLE
-
-
- TTTThhhheeee PPPPRRRROOOOTTTTOOOOTTTTYYYYPPPPEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword is similar to the PROTOTYPES: keyword above but can be used
- to force xxxxssssuuuubbbbpppppppp to use a specific prototype for the XSUB. This keyword
- overrides all other prototype options and keywords but affects only the
- current XSUB. Consult the Prototypes entry in the _p_e_r_l_s_u_b manpage for
- information about Perl prototypes.
-
- bool_t
- rpcb_gettime(timep, ...)
- time_t timep = NO_INIT
- PROTOTYPE: $;$
- PREINIT:
- char *host = "localhost";
- CODE:
- if( items > 1 )
- host = (char *)SvPV(ST(1), na);
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee AAAALLLLIIIIAAAASSSS:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The ALIAS: keyword allows an XSUB to have two or more unique Perl names
- and to know which of those names was used when it was invoked. The Perl
- names may be fully-qualified with package names. Each alias is given an
- index. The compiler will setup a variable called ix which contain the
- index of the alias which was used. When the XSUB is called with its
- declared name ix will be 0.
-
- The following example will create aliases FOO::gettime() and BAR::getit()
- for this function.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- ALIAS:
- FOO::gettime = 1
- BAR::getit = 2
- INIT:
- printf("# ix = %d\n", ix );
- OUTPUT:
- timep
-
-
-
-
-
-
- PPPPaaaaggggeeee 11115555
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TTTThhhheeee IIIINNNNCCCCLLLLUUUUDDDDEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword can be used to pull other files into the XS module. The
- other files may have XS code. INCLUDE: can also be used to run a command
- to generate the XS code to be pulled into the module.
-
- The file _R_p_c_b_1._x_s_h contains our rpcb_gettime() function:
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
- The XS module can use INCLUDE: to pull that file into it.
-
- INCLUDE: Rpcb1.xsh
-
- If the parameters to the INCLUDE: keyword are followed by a pipe (|) then
- the compiler will interpret the parameters as a command.
-
- INCLUDE: cat Rpcb1.xsh |
-
-
- TTTThhhheeee CCCCAAAASSSSEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The CASE: keyword allows an XSUB to have multiple distinct parts with
- each part acting as a virtual XSUB. CASE: is greedy and if it is used
- then all other XS keywords must be contained within a CASE:. This means
- nothing may precede the first CASE: in the XSUB and anything following
- the last CASE: is included in that case.
-
- A CASE: might switch via a parameter of the XSUB, via the ix ALIAS:
- variable (see the section on _T_h_e _A_L_I_A_S: _K_e_y_w_o_r_d), or maybe via the items
- variable (see the section on _V_a_r_i_a_b_l_e-_l_e_n_g_t_h _P_a_r_a_m_e_t_e_r _L_i_s_t_s). The last
- CASE: becomes the ddddeeeeffffaaaauuuulllltttt case if it is not associated with a
- conditional. The following example shows CASE switched via ix with a
- function rpcb_gettime() having an alias x_gettime(). When the function
- is called as rpcb_gettime() its parameters are the usual (char *host,
- time_t *timep), but when the function is called as x_gettime() its
- parameters are reversed, (time_t *timep, char *host).
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 11116666
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- long
- rpcb_gettime(a,b)
- CASE: ix == 1
- ALIAS:
- x_gettime = 1
- INPUT:
- # 'a' is timep, 'b' is host
- char *b
- time_t a = NO_INIT
- CODE:
- RETVAL = rpcb_gettime( b, &a );
- OUTPUT:
- a
- RETVAL
- CASE:
- # 'a' is host, 'b' is timep
- char *a
- time_t &b = NO_INIT
- OUTPUT:
- b
- RETVAL
-
- That function can be called with either of the following statements.
- Note the different argument lists.
-
- $status = rpcb_gettime( $host, $timep );
-
- $status = x_gettime( $timep, $host );
-
-
- TTTThhhheeee &&&& UUUUnnnnaaaarrrryyyy OOOOppppeeeerrrraaaattttoooorrrr
-
- The & unary operator is used to tell the compiler that it should
- dereference the object when it calls the C function. This is used when a
- CODE: block is not used and the object is a not a pointer type (the
- object is an int or long but not a int* or long*).
-
- The following XSUB will generate incorrect C code. The xsubpp compiler
- will turn this into code which calls rpcb_gettime() with parameters (char
- *host, time_t timep), but the real rpcb_gettime() wants the timep
- parameter to be of type time_t* rather than time_t.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t timep
- OUTPUT:
- timep
-
- That problem is corrected by using the & operator. The xsubpp compiler
- will now turn this into code which calls rpcb_gettime() correctly with
- parameters (char *host, time_t *timep). It does this by carrying the &
-
-
-
- PPPPaaaaggggeeee 11117777
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- through, so the function call looks like rpcb_gettime(host, &timep).
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
-
- IIIInnnnsssseeeerrrrttttiiiinnnngggg CCCCoooommmmmmmmeeeennnnttttssss aaaannnndddd CCCC PPPPrrrreeeepppprrrroooocccceeeessssssssoooorrrr DDDDiiiirrrreeeeccccttttiiiivvvveeeessss
-
- C preprocessor directives are allowed within BOOT:, PREINIT: INIT:,
- CODE:, PPCODE:, and CLEANUP: blocks, as well as outside the functions.
- Comments are allowed anywhere after the MODULE keyword. The compiler
- will pass the preprocessor directives through untouched and will remove
- the commented lines.
-
- Comments can be added to XSUBs by placing a # as the first non-whitespace
- of a line. Care should be taken to avoid making the comment look like a
- C preprocessor directive, lest it be interpreted as such. The simplest
- way to prevent this is to put whitespace in front of the #.
-
- If you use preprocessor directives to choose one of two versions of a
- function, use
-
- #if ... version1
- #else /* ... version2 */
- #endif
-
- and not
-
- #if ... version1
- #endif
- #if ... version2
- #endif
-
- because otherwise xsubpp will believe that you made a duplicate
- definition of the function. Also, put a blank line before the
- #else/#endif so it will not be seen as part of the function body.
-
- UUUUssssiiiinnnngggg XXXXSSSS WWWWiiiitttthhhh CCCC++++++++
-
- If a function is defined as a C++ method then it will assume its first
- argument is an object pointer. The object pointer will be stored in a
- variable called THIS. The object should have been created by C++ with
- the _n_e_w() function and should be blessed by Perl with the _s_v__s_e_t_r_e_f__p_v()
- macro. The blessing of the object by Perl can be handled by a typemap.
- An example typemap is shown at the end of this section.
-
-
-
-
-
-
- PPPPaaaaggggeeee 11118888
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- If the method is defined as static it will call the C++ function using
- the _c_l_a_s_s::_m_e_t_h_o_d() syntax. If the method is not static the function
- will be called using the THIS->_m_e_t_h_o_d() syntax.
-
- The next examples will use the following C++ class.
-
- class color {
- public:
- color();
- ~color();
- int blue();
- void set_blue( int );
-
- private:
- int c_blue;
- };
-
- The XSUBs for the _b_l_u_e() and _s_e_t__b_l_u_e() methods are defined with the
- class name but the parameter for the object (THIS, or "self") is implicit
- and is not listed.
-
- int
- color::blue()
-
- void
- color::set_blue( val )
- int val
-
- Both functions will expect an object as the first parameter. The xsubpp
- compiler will call that object THIS and will use it to call the specified
- method. So in the C++ code the _b_l_u_e() and _s_e_t__b_l_u_e() methods will be
- called in the following manner.
-
- RETVAL = THIS->blue();
-
- THIS->set_blue( val );
-
- If the function's name is DDDDEEEESSSSTTTTRRRROOOOYYYY then the C++ delete function will be
- called and THIS will be given as its parameter.
-
- void
- color::DESTROY()
-
- The C++ code will call delete.
-
- delete THIS;
-
- If the function's name is nnnneeeewwww then the C++ new function will be called to
- create a dynamic C++ object. The XSUB will expect the class name, which
- will be kept in a variable called CLASS, to be given as the first
- argument.
-
-
-
-
- PPPPaaaaggggeeee 11119999
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- color *
- color::new()
-
- The C++ code will call new.
-
- RETVAL = new color();
-
- The following is an example of a typemap that could be used for this C++
- example.
-
- TYPEMAP
- color * O_OBJECT
-
- OUTPUT
- # The Perl object is blessed into 'CLASS', which should be a
- # char* having the name of the package for the blessing.
- O_OBJECT
- sv_setref_pv( $arg, CLASS, (void*)$var );
-
- INPUT
- O_OBJECT
- if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
- $var = ($type)SvIV((SV*)SvRV( $arg ));
- else{
- warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
- XSRETURN_UNDEF;
- }
-
-
- IIIInnnntttteeeerrrrffffaaaacccceeee SSSSttttrrrraaaatttteeeeggggyyyy
-
- When designing an interface between Perl and a C library a straight
- translation from C to XS is often sufficient. The interface will often
- be very C-like and occasionally nonintuitive, especially when the C
- function modifies one of its parameters. In cases where the programmer
- wishes to create a more Perl-like interface the following strategy may
- help to identify the more critical parts of the interface.
-
- Identify the C functions which modify their parameters. The XSUBs for
- these functions may be able to return lists to Perl, or may be candidates
- to return undef or an empty list in case of failure.
-
- Identify which values are used by only the C and XSUB functions
- themselves. If Perl does not need to access the contents of the value
- then it may not be necessary to provide a translation for that value from
- C to Perl.
-
- Identify the pointers in the C function parameter lists and return
- values. Some pointers can be handled in XS with the & unary operator on
- the variable name while others will require the use of the * operator on
- the type name. In general it is easier to work with the & operator.
-
-
-
-
- PPPPaaaaggggeeee 22220000
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- Identify the structures used by the C functions. In many cases it may be
- helpful to use the T_PTROBJ typemap for these structures so they can be
- manipulated by Perl as blessed objects.
-
- PPPPeeeerrrrllll OOOObbbbjjjjeeeeccccttttssss AAAAnnnndddd CCCC SSSSttttrrrruuuuccccttttuuuurrrreeeessss
-
- When dealing with C structures one should select either TTTT____PPPPTTTTRRRROOOOBBBBJJJJ or
- TTTT____PPPPTTTTRRRRRRRREEEEFFFF for the XS type. Both types are designed to handle pointers to
- complex objects. The T_PTRREF type will allow the Perl object to be
- unblessed while the T_PTROBJ type requires that the object be blessed.
- By using T_PTROBJ one can achieve a form of type-checking because the
- XSUB will attempt to verify that the Perl object is of the expected type.
-
- The following XS code shows the _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() function which is used
- with ONC+ TIRPC. The _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() function will return a pointer to
- a C structure and has the C prototype shown below. The example will
- demonstrate how the C pointer will become a Perl reference. Perl will
- consider this reference to be a pointer to a blessed object and will
- attempt to call a destructor for the object. A destructor will be
- provided in the XS source to free the memory used by _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t().
- Destructors in XS can be created by specifying an XSUB function whose
- name ends with the word DDDDEEEESSSSTTTTRRRROOOOYYYY. XS destructors can be used to free
- memory which may have been malloc'd by another XSUB.
-
- struct netconfig *getnetconfigent(const char *netid);
-
- A typedef will be created for struct netconfig. The Perl object will be
- blessed in a class matching the name of the C type, with the tag Ptr
- appended, and the name should not have embedded spaces if it will be a
- Perl package name. The destructor will be placed in a class
- corresponding to the class of the object and the PREFIX keyword will be
- used to trim the name to the word DESTROY as Perl will expect.
-
- typedef struct netconfig Netconfig;
-
- MODULE = RPC PACKAGE = RPC
-
- Netconfig *
- getnetconfigent(netid)
- char *netid
-
- MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
-
- void
- rpcb_DESTROY(netconf)
- Netconfig *netconf
- CODE:
- printf("Now in NetconfigPtr::DESTROY\n");
- free( netconf );
-
- This example requires the following typemap entry. Consult the typemap
- section for more information about adding new typemaps for an extension.
-
-
-
- PPPPaaaaggggeeee 22221111
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TYPEMAP
- Netconfig * T_PTROBJ
-
- This example will be used with the following Perl statements.
-
- use RPC;
- $netconf = getnetconfigent("udp");
-
- When Perl destroys the object referenced by $netconf it will send the
- object to the supplied XSUB DESTROY function. Perl cannot determine, and
- does not care, that this object is a C struct and not a Perl object. In
- this sense, there is no difference between the object created by the
- _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() XSUB and an object created by a normal Perl subroutine.
-
- TTTThhhheeee TTTTyyyyppppeeeemmmmaaaapppp
-
- The typemap is a collection of code fragments which are used by the
- xxxxssssuuuubbbbpppppppp compiler to map C function parameters and values to Perl values.
- The typemap file may consist of three sections labeled TYPEMAP, INPUT,
- and OUTPUT. The INPUT section tells the compiler how to translate Perl
- values into variables of certain C types. The OUTPUT section tells the
- compiler how to translate the values from certain C types into values
- Perl can understand. The TYPEMAP section tells the compiler which of the
- INPUT and OUTPUT code fragments should be used to map a given C type to a
- Perl value. Each of the sections of the typemap must be preceded by one
- of the TYPEMAP, INPUT, or OUTPUT keywords.
-
- The default typemap in the ext directory of the Perl source contains many
- useful types which can be used by Perl extensions. Some extensions
- define additional typemaps which they keep in their own directory. These
- additional typemaps may reference INPUT and OUTPUT maps in the main
- typemap. The xxxxssssuuuubbbbpppppppp compiler will allow the extension's own typemap to
- override any mappings which are in the default typemap.
-
- Most extensions which require a custom typemap will need only the TYPEMAP
- section of the typemap file. The custom typemap used in the
- _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() example shown earlier demonstrates what may be the
- typical use of extension typemaps. That typemap is used to equate a C
- structure with the T_PTROBJ typemap. The typemap used by
- _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() is shown here. Note that the C type is separated from
- the XS type with a tab and that the C unary operator * is considered to
- be a part of the C type name.
-
- TYPEMAP
- Netconfig *<tab>T_PTROBJ
-
- Here's a more complicated example: suppose that you wanted struct
- netconfig to be blessed into the class Net::Config. One way to do this
- is to use underscores (_) to separate package names, as follows:
-
-
-
-
-
-
- PPPPaaaaggggeeee 22222222
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- typedef struct netconfig * Net_Config;
-
- And then provide a typemap entry T_PTROBJ_SPECIAL that maps underscores
- to double-colons (::), and declare Net_Config to be of that type:
-
- TYPEMAP
- Net_Config T_PTROBJ_SPECIAL
-
- INPUT
- T_PTROBJ_SPECIAL
- if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")) {
- IV tmp = SvIV((SV*)SvRV($arg));
- $var = ($type) tmp;
- }
- else
- croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")
-
- OUTPUT
- T_PTROBJ_SPECIAL
- sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\",
- (void*)$var);
-
- The INPUT and OUTPUT sections substitute underscores for double-colons on
- the fly, giving the desired effect. This example demonstrates some of
- the power and versatility of the typemap facility.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
- File RPC.xs: Interface to some ONC+ RPC bind library functions.
-
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
-
- #include <rpc/rpc.h>
-
- typedef struct netconfig Netconfig;
-
- MODULE = RPC PACKAGE = RPC
-
- SV *
- rpcb_gettime(host="localhost")
- char *host
- PREINIT:
- time_t timep;
- CODE:
- ST(0) = sv_newmortal();
- if( rpcb_gettime( host, &timep ) )
- sv_setnv( ST(0), (double)timep );
-
- Netconfig *
- getnetconfigent(netid="udp")
- char *netid
-
-
-
- PPPPaaaaggggeeee 22223333
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
-
- void
- rpcb_DESTROY(netconf)
- Netconfig *netconf
- CODE:
- printf("NetconfigPtr::DESTROY\n");
- free( netconf );
-
- File typemap: Custom typemap for RPC.xs.
-
- TYPEMAP
- Netconfig * T_PTROBJ
-
- File RPC.pm: Perl module for the RPC extension.
-
- package RPC;
-
- require Exporter;
- require DynaLoader;
- @ISA = qw(Exporter DynaLoader);
- @EXPORT = qw(rpcb_gettime getnetconfigent);
-
- bootstrap RPC;
- 1;
-
- File rpctest.pl: Perl test program for the RPC extension.
-
- use RPC;
-
- $netconf = getnetconfigent();
- $a = rpcb_gettime();
- print "time = $a\n";
- print "netconf = $netconf\n";
-
- $netconf = getnetconfigent("tcp");
- $a = rpcb_gettime("poplar");
- print "time = $a\n";
- print "netconf = $netconf\n";
-
-
- XXXXSSSS VVVVEEEERRRRSSSSIIIIOOOONNNN
- This document covers features supported by xsubpp 1.935.
-
- AAAAUUUUTTTTHHHHOOOORRRR
- Dean Roehrich <_r_o_e_h_r_i_c_h@_c_r_a_y._c_o_m> Jul 8, 1996
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 22224444
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 22225555
-
-
-
-
-
-
-